import {
  Controller,
  Get,
  Post,
  Body,
  HttpException,
  HttpStatus,
  Param,
  ParseIntPipe,
  UseGuards,
} from '@nestjs/common';
import { CatsService } from './cats.service';
import { CreateCatDto } from './create-cat.dto';
import { Cat } from './cat.interface';
import { ForbiddenException } from 'src/common/exception/forbidden.exception';
import { Roles } from '../common/roles/roles.decorator';
import { RolesGuard } from '../common/roles/roles.guard';

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {
  /**
   * Nest 将通过创建并返回 CatsService 的实例来解析 catsService
   * （或者，在单例的正常情况下，如果已在其他地方请求过，则返回现有实例）。
   * 此依赖已解析并传递给控制器的构造函数（或分配给指示的属性）：
   */
  constructor(private readonly catsService: CatsService) {}

  @Post('/create')
  @Roles(['admin']) // 表明只有具有 admin 角色的用户才可以访问此路由。
  public async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get('/all')
  public async getAllCats(): Promise<Cat[]> {
    return this.catsService.findAll();
  }

  @Get('/error')
  public async getError() {
    /**
     * HttpException 构造函数采用两个必需的参数来确定响应：
     *  - response 参数定义 JSON 响应主体。它可以是 string 或 object，如下所述。
     *  - status 参数定义了 HTTP 状态代码。
     */
    // throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
    // 自定义响应
    // throw new HttpException(
    //   { status: HttpStatus.FORBIDDEN, message: 'This is a custom message' },
    //   HttpStatus.FORBIDDEN,
    // );

    // 自定义异常
    throw new ForbiddenException();
  }

  /**
   * 管道
   * 管道都在验证路由参数、查询字符串参数和请求正文值的上下文中工作。
   */
  // 传递管道类
  // @Get(':id')
  // async findOne(@Param('id', ParseIntPipe) id: number) {
  //   return this.catsService.findOne(id);
  // }
  // 传递实例, 通过传递选项来自定义内置管道的行为
  @Get(':id')
  async findOne(
    @Param(
      'id',
      new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }),
    )
    id: number,
  ) {
    return this.catsService.findOne(id);
  }
}
